<?php

require_once(dirname(__FILE__) . '/EventDispatcher.php');

/**
 * Description of TaskQueue
 *
 * @author Gvozd
 */
class TaskQueue extends EventDispatcher {

    /**
     *
     * @var array
     */
    public $queue = array();

    /**
     *
     * @var array
     */
    private $on_process = array();

    /**
     *
     * @var <type>
     */
    public $count_threads;

    /**
     *
     * @param int $threads
     */
    public function __construct($threads = 10) {
        $this->count_threads = $threads;
    }

    /**
     *
     * @param Task $task
     */
    public function addTask(Task $task) {
        array_push($this->queue, $task);
        $this->startExecuteTasks();
    }

    /**
     *
     * @param Task $task
     */
    public function removeTaskFromQueue(Task $task) {
        $deleteKeys = array_keys($this->queue, $task);
        foreach ($deleteKeys as $key) {
            unset($this->queue[$key]);
        }
        $this->startExecuteTasks();
    }

    /**
     *
     * @param Task $task
     */
    public function removeTaskFromProcess(Task $task) {
        //echo "taskEnded".count($this->on_process);
        $deleteKeys = array_keys($this->on_process, $task);
        foreach ($deleteKeys as $key) {
            unset($this->on_process[$key]);
        }
        //echo "|".count($this->on_process)."<br>\n";
        //echo "|".count($this->queue)."<br>\n";
    }

    /**
     * 
     */
    public function startExecuteTasks() {
        while (count($this->on_process) < $this->count_threads && count($this->queue)) {
            $task = array_shift($this->queue);
            $task->addEventListener('taskEnded', array($this, 'taskEndedListener'));
            array_push($this->on_process, $task);
            $task->startExecution();
        }
    }

    public function taskEndedListener(Event $event) {
        $this->removeTaskfromProcess($event->target);
        $event->target->removeEventListener($event->type, $event->callee);
        $this->startExecuteTasks();
    }

    public function hasExecuted() {
        return ( count($this->queue) + count($this->on_process) ) > 0;
    }

}

?>
